package cn.ewan.cloud.tenant.data.router.core.business.plugin.db.mysql.sharding;

import cn.ewan.cloud.common.support.Log;
import cn.ewan.cloud.tenant.data.router.core.common.util.TenantLog;
import org.apache.shardingsphere.sql.parser.binder.metadata.schema.SchemaMetaData;
import org.apache.shardingsphere.underlying.route.context.RouteContext;
import org.apache.shardingsphere.underlying.route.context.RouteMapper;
import org.apache.shardingsphere.underlying.route.context.RouteUnit;
import org.apache.shardingsphere.underlying.route.hook.RoutingHook;

import java.util.Collection;
import java.util.LinkedHashSet;

/**
 * @author lgh
 * @date 2022/12/14 16:54
 */
public class ShardingHook implements RoutingHook {

    /**
     * 数据库的多租户处理器
     */
    private final MysqlKeyPlugin mysqlTenantProcess;


    public ShardingHook() {
        mysqlTenantProcess = new MysqlKeyPlugin();
    }

    @Override
    public void start(String s) {

    }

    @Override
    public void finishSuccess(RouteContext routeContext, SchemaMetaData schemaMetaData) {
        Collection<RouteUnit> routeUnits = routeContext.getRouteResult().getRouteUnits();
        Log.NORMAL.info("[sharding jdb plugin] origin routeUnits={}", routeUnits);
        //多租户处理
        Collection<RouteUnit> routeUnitsTmp = tenantDbBuild(routeUnits);
        //更新处理后结果
        routeUnits.clear();
        routeUnits.addAll(routeUnitsTmp);
        TenantLog.log("sharding db final routeUnits", routeUnits);
    }


    /**
     * 数据库作多租户逻辑处理
     *
     * @param routeUnits
     * @return
     */
    private Collection<RouteUnit> tenantDbBuild(Collection<RouteUnit> routeUnits) {
        Collection<RouteUnit> routeUnitsTmp = new LinkedHashSet<>();
        for (RouteUnit routeUnit : routeUnits) {
            RouteMapper dbTmp = routeUnit.getDataSourceMapper();
            RouteMapper routeMapper = new RouteMapper(dbTmp.getLogicName(),
                    mysqlTenantProcess.convertTenantTag(dbTmp.getActualName()));
            routeUnitsTmp.add(new RouteUnit(routeMapper, routeUnit.getTableMappers()));
        }
        return routeUnitsTmp;
    }


    @Override
    public void finishFailure(Exception e) {

    }
}
